package register;

import com.xiguanlezz.cn.api.remote.request.*;
import com.xiguanlezz.cn.api.remote.response.HealthCheckResponse;
import com.xiguanlezz.cn.api.remote.response.InstanceResponse;
import com.xiguanlezz.cn.api.remote.response.ServerCheckResponse;
import com.xiguanlezz.cn.api.remote.response.SubscribeServiceResponse;
import com.xiguanlezz.cn.client.naming.core.ServerListManager;
import com.xiguanlezz.cn.client.env.NacosClientProperties;
import com.xiguanlezz.cn.common.remote.ConnectionType;
import com.xiguanlezz.cn.common.remote.PayloadRegistry;
import com.xiguanlezz.cn.common.remote.client.Connection;
import com.xiguanlezz.cn.common.remote.client.RpcClient;
import com.xiguanlezz.cn.common.remote.client.RpcClientStatus;
import com.xiguanlezz.cn.common.remote.client.grpc.DefaultGrpcClientConfig;
import com.xiguanlezz.cn.common.remote.client.grpc.GrpcClient;
import com.xiguanlezz.cn.common.remote.client.grpc.GrpcConnection;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.util.Objects;
import java.util.Properties;

/**
 * @Author：习惯了种种
 * @CreateDate：2024/11/19 21:01
 * @Description：
 */
public class _3_网络通信 {

    @Test
    public void rpcClientStatus() throws Exception {
        // 连接为空的假客户端
        RpcClient fakeRpcClient = new RpcClient(new DefaultGrpcClientConfig("grpc")) {
            @Override
            public ConnectionType getConnectionType() {
                return ConnectionType.GRPC;
            }

            @Override
            public int rpcPortOffset() {
                return 1000;
            }

            @Override
            public Connection connectToServer(ServerInfo serverInfo) throws Exception {
                return null;
            }
        };
        Properties properties = new Properties() {{
            put("serverAddr", "127.0.0.1:8848");
        }};
        Assert.assertEquals(RpcClientStatus.WAIT_INIT, fakeRpcClient.getRpcClientStatus().get());
        NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
        fakeRpcClient.serverListFactory(new ServerListManager("hangzhou", nacosClientProperties));
        Assert.assertEquals(RpcClientStatus.INITIALIZED, fakeRpcClient.getRpcClientStatus().get());
        fakeRpcClient.start();
        Assert.assertEquals(RpcClientStatus.STARTING, fakeRpcClient.getRpcClientStatus().get());
        fakeRpcClient.shutdown();
        Assert.assertEquals(RpcClientStatus.SHUTDOWN, fakeRpcClient.getRpcClientStatus().get());

        // 真客户端
        RpcClient rpcClient = new RpcClient(new DefaultGrpcClientConfig("grpc")) {
            @Override
            public ConnectionType getConnectionType() {
                return ConnectionType.GRPC;
            }

            @Override
            public int rpcPortOffset() {
                return 1000;
            }

            @Override
            public Connection connectToServer(ServerInfo serverInfo) throws Exception {
                return new GrpcConnection(new ServerInfo("127.0.0.1", 8848));
            }
        };
        Assert.assertEquals(RpcClientStatus.WAIT_INIT, rpcClient.getRpcClientStatus().get());
        nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
        rpcClient.serverListFactory(new ServerListManager("hangzhou", nacosClientProperties));
        Assert.assertEquals(RpcClientStatus.INITIALIZED, rpcClient.getRpcClientStatus().get());
        rpcClient.start();
        Assert.assertEquals(RpcClientStatus.RUNNING, rpcClient.getRpcClientStatus().get());
        rpcClient.shutdown();
        Assert.assertEquals(RpcClientStatus.SHUTDOWN, rpcClient.getRpcClientStatus().get());
    }

    @Test
    public void payloadRegistry() {
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(ServerCheckResponse.class.getSimpleName())));
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(HealthCheckResponse.class.getSimpleName())));
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(InstanceResponse.class.getSimpleName())));
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(SubscribeServiceResponse.class.getSimpleName())));
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(SetupAckRequest.class.getSimpleName())));
        Assert.assertTrue(Objects.nonNull(PayloadRegistry.getClassByType(NotifySubscriberRequest.class.getSimpleName())));
    }

    @Test
    public void grpcTransportPort() throws IOException {
        GrpcClient grpcClient = new GrpcClient("grpc");
        // 只需要连接Nacos服务端祝地址即可，connectToServer内部会自己处理偏移量
        RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo("localhost", 8848);
        grpcClient.connectToServer(serverInfo);
    }
}
